#ifndef CIOPS_OP_CREATESPHERE_H
#define CIOPS_OP_CREATESPHERE_H

#include <strstream>

#include "Operation.h"

namespace CIOps {
    /**
     * This class represents the operation of creation of a sphere   
     **/
    class OP_CreateSphere : public Operation {    

    public:            
        OP_CreateSphere (std::vector<CIView::View*>& v);        //Constructor
        virtual ~OP_CreateSphere();                             //Destructor

    protected:
        //The X and Z coordinates of the Icosahedron centered at the origin (having a circumscribed sphere of radius 1) 
        static const float X;                               
        static const float Z;                                 

        static const unsigned int ICOSA_TRIANGLES_INDICES[20][3];   //The Icosahedron 20 triangular faces (defined through the 12 vertices)
        static const float ICOSA_VERTICES[12][3];                   //The Icosahedron 12 vertices

        CIGeom::Geometry* sphere;           //A pointer to the sphere that will be added in the 3D scene
        CICore::Point centre;               //The sphere's centre
        float radius;                       //The sphere's radius

        int stacks;                         //The number of stacks (for the cone subdivision in faces)
        int slices;                         //The number of slices (for the cone subdivision in faces)

        short sphereDetail;                 //The sphere tessellation detail

        //Methods for Triangles Tessellation of a sphere
        void CreateRecursiveTriangles (const float* x, const float* y, const float* z, unsigned int d, float r);
        void CreateSphereFromIcosahedron (unsigned int detail, float radius);

        //Inline Method to normalize a vertex
        inline static void NormalizeVertex (float *v) {
            float d = sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
            v[0] /= d;   v[1] /= d;    v[2] /= d;
        }

        void CreateSphereWithTriangles (int stacks, int slices, float radius);
        void AddFace (int v1, int v2, int v3);      
        

    public:            
        //Utility Methods
        virtual int Exec();         //Method called to execute directly the operation
        virtual void Undo();        //Method called to undo the operation
        virtual void Redo();        //Method called to redo the operation

        virtual void MousePressEvent (CIView::View* view, QMouseEvent* e);        //Mouse Pressed event handler
        virtual void MouseReleaseEvent (CIView::View* view, QMouseEvent* e);      //Mouse Released event handler
        virtual void MouseMoveEvent (CIView::View* view, QMouseEvent* e);         //Mouse Moved event handler
        virtual void WheelEvent (CIView::View* view, QWheelEvent* e);             //Wheel event handler
    };
}

#endif /* CIOPS_OP_CREATESPHERE_H */
